package com.ggb.reactive.controller.admin

import com.ggb.reactive.constant.UPLOAD_FAILED
import com.ggb.reactive.extension.log
import com.ggb.reactive.utils.AliOssUtil
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import lombok.RequiredArgsConstructor
import org.springframework.http.codec.multipart.FilePart
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile
import reactor.core.publisher.Mono
import com.ggb.reactive.model.Result
import java.util.*

@RestController
@RequestMapping("/admin/common")
@Tag(name = "公共接口")
@RequiredArgsConstructor
class CommonController(private val aliOssUtil: AliOssUtil) {

    @PostMapping("/upload")
    @Operation(description = "文件上传")
    fun upload(file: Mono<FilePart>): Mono<Result<String>> {
        log.info("文件上传: {}",file);
        return file.flatMap { part ->
            val originalFilename = part.filename()
            val extension = originalFilename.substringAfterLast('.', "")
            val objectName = "${UUID.randomUUID()}${if (extension.isNotEmpty()) ".$extension" else ""}"

            part.content().collectList().map { dataBufferList ->
                val allBytes = dataBufferList.flatMap { dataBuffer ->
                    val bytes = ByteArray(dataBuffer.readableByteCount())
                    dataBuffer.read(bytes)
                    bytes.toList()
                }.toByteArray()

                // 释放DataBuffer资源的操作通常不是必需的，框架会处理
                aliOssUtil.upload(allBytes, objectName)
            }.map { filePath ->
                Result.success(filePath)
            }.doOnError { e ->
                log.error("文件上传失败", e)
                Result.error<String>(UPLOAD_FAILED)
            }
        }.onErrorResume { e ->
            log.error("处理文件上传时发生错误", e)
            Mono.just(Result.error(UPLOAD_FAILED))
        }
    }
}